/*   线程-Thread   */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <pthread.h>
#include <errno.h>

static void exit_handler(void) {
    printf("Over!\n");
}

static void *thread_start(void *arg) {
    int ret;
    //pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);  //忽略取消响应
    // ret = pthread_detach(pthread_self()); //自行分离
    // if(ret != 0) {
    //     fprintf(stderr,"pthread_detach error: %s",strerror(ret));
    //     pthread_exit(NULL);
    // }
    printf("新线程: 进程ID<%d>  子线程ID<%lu>\n", getpid(), pthread_self()); 
    while(1) {
        pthread_testcancel();   //该函数可以自己产生取消点，接受到取消请求时，自动取消
    }
    pthread_exit((void *)10);
}

int main(int argc,char **argv)
{
    if(-1 == atexit(exit_handler)) {
        perror("atexit error");
        exit(-1);
    }

    printf("主线程: 进程ID<%d>  主线程ID<%lu>\n",getpid(), pthread_self()); 

    pthread_t tid;
    int ret;

    ret = pthread_create(&tid, NULL, thread_start, NULL); 
    if (ret != 0) {
        fprintf(stderr, "pthread_create error: %s\n", strerror(ret)); 
        exit(-1);
    }
    sleep(1);   //新建线程后，休眠一秒，确保新线程自行分离

    // 向新线程发送取消请求
    ret = pthread_cancel(tid);
    if(ret != 0) {
        fprintf(stderr,"pthread_cancel error: %s\n",strerror(ret));
        exit(-1);
    }

    // 使用pthread_join等待线程结束，可靠回收资源
    void* tret;
    ret = pthread_join(tid, &tret);
    if (ret != 0) { //阻塞等待
        fprintf(stderr, "pthread_join error: %s\n", strerror(ret));
        exit(-1);
    }
    printf("新线程终止,code=%ld\n",(long)tret);

    exit(0);
}
